package datastructuur;

import java.util.ArrayList;

public class Grammatica {
	private ArrayList<Regel> regels = new ArrayList<Regel>();

	public Grammatica() {
	}

	public void addRegel(Regel regel) {
		regels.add(regel);
	}

	public void setStarters() {
		for (Regel r : regels) {
			NonTerminal gedefinieerde = r.getGedefinieerde();
			for (Alternatief a : r.getAlternatieven()) {
				if (a.getTerm(0) instanceof Terminal) {
					if(!a.getTerm(0).getNaam().equals("E"))
					{
						gedefinieerde.addStarter(a.getTerm(0));
					}
					
				}

				else {
					for (Term t : getStarters((NonTerminal) a.getTerm(0))) {
						gedefinieerde.addStarter(t);
					}
				}
			}
		}
	}

	public ArrayList<Term> getStarters(NonTerminal gedefinieerde) {
		for (Regel r : regels) {
			if (r.getGedefinieerde().getNaam().equals(gedefinieerde.getNaam())) {
				for (Alternatief a : r.getAlternatieven()) {
					if (a.getTerm(0) instanceof Terminal) {
						if(!a.getTerm(0).getNaam().equals("E"))
						{
							gedefinieerde.addStarter(a.getTerm(0));
						}
					} else {
						for (Term t : getStarters((NonTerminal) a.getTerm(0))) {
							gedefinieerde.addStarter(t);
						}
					}
				}
			}
		}
		return gedefinieerde.getStarters();
	}
	
	
	public void setFollowers()
	{
		for(Regel r : regels)
		{
			NonTerminal gedefinieerde = r.getGedefinieerde();
			for(Regel r2 : regels)
			{
				if(r2.contains(gedefinieerde))
				{
					for(Alternatief a : r2.getAlternatieven()){
						int i = a.getTermen().indexOf(gedefinieerde);
						if(i == a.getTermen().size()-1)
						{
							for(Term t : setFollowers(r.getGedefinieerde()))
							{
								gedefinieerde.addFollower(t);
							}
						}
						else
						{
							if(a.getTerm(i+1) instanceof Terminal)
							{
								gedefinieerde.addFollower(a.getTerm(i+1));
							}
							else
							{
								for(Term t : ((NonTerminal)a.getTerm(i+1)).getStarters())
								{
									gedefinieerde.addFollower(t);
								}
							}
						}
					}
				}
			}
		}
	}
	
	public ArrayList<Term> setFollowers(NonTerminal gedefinieerde)
	{
		for (Regel r2 : regels) {
			if (r2.contains(gedefinieerde)) {
				for (Alternatief a : r2.getAlternatieven()) {
					int i = a.getTermen().indexOf(gedefinieerde);
					if (i == a.getTermen().size() - 1) {
						for(Term t : setFollowers(r2.getGedefinieerde()))
						{
							gedefinieerde.addFollower(t);
						}
					} else {
						if (a.getTerm(i + 1) instanceof Terminal) {
							gedefinieerde.addFollower(a.getTerm(i + 1));
						} else {
							for (Term t : ((NonTerminal) a.getTerm(i + 1)).getStarters()) {
								gedefinieerde.addFollower(t);
							}
						}
					}
				}
			}
		}
		return gedefinieerde.getFollowers();
	}

	
	public String toString() {
		String s = "";
		for (Regel r : regels) {
			s += r + "\n";
		}
		return s;
	}
	public void printStarters(){
		
		System.out.print("----STARTERS----");
		for(Regel r : regels){
			r.getGedefinieerde().printStarters();
		}
	}
	public void printFollowers()
	{
		System.out.println("\n\n----FOLLOWERS----");
		for(Regel r : regels)
		{
			r.getGedefinieerde().printFollowers();
		}
	}
}
